package com.lamatek.tags.google.beans;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

/**
 * USAddressGeocoder
 * @author Tom Cole
 * @version 0.40
 * 
 * This class takes a US address and attempts to geocode it to
 * longitude/latitude using the Yahoo Geocoding API.
 * 
 * Developers should not override this class, but rather should override
 * the Geocoder.geocode() method to call the geocoder of their choice.
 */
public class USAddressGeocoder implements Geocoder, Serializable {
    
    String zipcode = null;
    String state = null;
    String city = null;
    String address = null;
    String country = null;
    double longitude = 0.00d;
    double latitude = 0.00d;
    String precision = null;
    String warning = null;

    public void setAddress(String address) {
        this.address = address;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public void setState(String state) {
        this.state = state;
    }
    public void setCountry(String country) {
       this.country = country;
    }
    public void setZip(String zip) {
        this.zipcode = zip;
    }
    public boolean geocode() {
        try {
            String path = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=google-jsp-taglib";
            if (address != null) 
                path += "&street=" + URLEncoder.encode(address, "UTF-8");
            if (city != null)
                path += "&city=" + URLEncoder.encode(city, "UTF-8");
            if (state != null) 
                path += "&state=" + URLEncoder.encode(state, "UTF-8");
            if (zipcode != null)
                path += "&zip=" + URLEncoder.encode(zipcode, "UTF-8");
            URLConnection con = new URL(path).openConnection();
            if (con != null) {
                BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String line = "";
                while ((line = input.readLine()) != null) {
                    if (line.indexOf("<Latitude>") > 0) {
                        int start = line.indexOf("<Latitude>") + 10;
                        int end = line.indexOf("</Latitude>", start);
                        String value = line.substring(start, end).trim();
                        try {
                            latitude = Double.parseDouble(value);
                        }
                        catch(Exception ex) {
                            ex.printStackTrace(System.err);
                            return false;
                        }
                    }
                    if (line.indexOf("<Longitude>") > 0) {
                        int start = line.indexOf("<Longitude>") + 11;
                        int end = line.indexOf("</Longitude>", start);
                        String value = line.substring(start, end).trim();
                        try {
                            longitude = Double.parseDouble(value);
                        }
                        catch(Exception ex) {
                            ex.printStackTrace(System.err);
                            return false;
                        }
                    }
                    if (line.indexOf("<Result") > 0 && line.indexOf("precision") > 0) {
                        int start = line.indexOf("precision=\"") + 11;
                        int end = line.indexOf("\"", start);
                        String precision = line.substring(start, end).trim();
                    }
                    if (line.indexOf("<Result") > 0 && line.indexOf("warning") > 0) {
                        int start = line.indexOf("warning=\"") + 9;
                        int end = line.indexOf("\"", start);
                        String warning = line.substring(start, end).trim();
                    }
                }
                input.close();
                return true;
            }
            else {
                return false;
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
    public double getLongitude() {
        return longitude;
    }
    public double getLatitude() {
        return latitude;
    }
    public String getPrecision() {
        return precision;
    }
    public String getWarning() {
        return warning;
    }
}
